﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Company.Shell.Controls
{
    public class Gauge : Control
    {
        RotateTransform? rotateTransform;
        Grid? container;
        public Gauge()
        {
            Width = 200;
            Height = 200;
        }

        static Gauge()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Gauge),new FrameworkPropertyMetadata(typeof(Gauge)));
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            rotateTransform = GetTemplateChild("PointRotate") as RotateTransform;
            container = GetTemplateChild("container") as Grid;
            if (rotateTransform != null && container != null)
            {
                Initialize();
            }
        }

        private void Initialize()
        {
            double angle = -140;//开始角度
            double total = Math.Abs(angle * 2);
            double bigStep = total / 10;//大刻度步长
            double smallStep = bigStep / 10;//小刻度步长

            //画刻度线
            for (int i = 0; i <= 10; i++)
            {
                Line line = new Line();
                line.X1 = 0;
                line.Y1 = 0;
                line.X2 = 0;
                line.Y2 = 12;
                line.Stroke = Brushes.White;
                line.StrokeThickness = 2;
                line.HorizontalAlignment = HorizontalAlignment.Center;
                line.RenderTransformOrigin = new Point(0.5, 0.5);
                line.RenderTransform = new RotateTransform() { Angle=angle+i*bigStep};
                container.Children.Add(line);

                //画文字
                var per = MaxValue / 10;
                TextBlock textBlock = new TextBlock();
                textBlock.Text = $"{MinValue + (per * i)}";
                textBlock.HorizontalAlignment = HorizontalAlignment.Center;
                textBlock.RenderTransformOrigin = new Point(0.5, 0.5);
                textBlock.RenderTransform = new RotateTransform() { Angle = angle + i * bigStep };
                textBlock.Margin = new Thickness(12);
                textBlock.Foreground = Brushes.White;
                textBlock.FontSize = 12;
                container.Children.Add(textBlock);

                //画小刻度
                var start = (line.RenderTransform as RotateTransform).Angle + smallStep;
                for (int j = 0; j < 9 && i < 10; j++)
                {
                    line = new Line();
                    line.X1 = 0;
                    line.Y1 = 0;
                    line.X2 = 0;
                    line.Y2 = 6;
                    line.Stroke = Brushes.White;
                    line.StrokeThickness = 1;
                    line.HorizontalAlignment = HorizontalAlignment.Center;
                    line.RenderTransformOrigin = new Point(0.5, 0.5);
                    line.RenderTransform = new RotateTransform() { Angle = start + j * smallStep };
                    container.Children.Add(line);
                }
            }
        }


        /// <summary>
        /// 仪表盘最小值
        /// </summary>
        public double MinValue
        {
            get { return (double)GetValue(MinValueProperty); }
            set { SetValue(MinValueProperty, value); }
        }

        public static readonly DependencyProperty MinValueProperty =
            DependencyProperty.Register("MinValue", typeof(double), typeof(Gauge), new PropertyMetadata(0d,OnValueChanged));

        /// <summary>
        /// 仪表盘最大值
        /// </summary>
        public double MaxValue
        {
            get { return (double)GetValue(MaxValueProperty); }
            set { SetValue(MaxValueProperty, value); }
        }

        public static readonly DependencyProperty MaxValueProperty =
            DependencyProperty.Register("MaxValue", typeof(double), typeof(Gauge), new PropertyMetadata(100d, OnValueChanged));



        /// <summary>
        /// 当前值
        /// </summary>
        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(double), typeof(Gauge), new PropertyMetadata(50d, OnValueChanged));


        /// <summary>
        /// 指针颜色
        /// </summary>
        public Brush PointerColor
        {
            get { return (Brush)GetValue(PointerColorProperty); }
            set { SetValue(PointerColorProperty, value); }
        }

        public static readonly DependencyProperty PointerColorProperty =
            DependencyProperty.Register("PointerColor", typeof(Brush), typeof(Gauge), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(15,169,206))));


        /// <summary>
        /// 标题
        /// </summary>
        public string  Title
        {
            get { return (string )GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }

        public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register("Title", typeof(string ), typeof(Gauge), new PropertyMetadata("标题", OnValueChanged));





        private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var contrtol = d as Gauge;
            if (contrtol != null)
            {
                contrtol.Refresh();
            }
        }

        private void Refresh()
        {
            if (rotateTransform == null) return;
            DoubleAnimation da = new DoubleAnimation();
            da.Duration = new Duration(TimeSpan.FromMicroseconds(350));
            da.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut };
            if (Value > MaxValue)
            {
                rotateTransform.Angle = 140;
                da.To = 140;
            }
            else if (Value < MinValue)
            {
                rotateTransform.Angle = -140;
                da.To = -140;
            }
            else
            {
                var range = MaxValue - MinValue;
                var process = Value / range;
                var tAngle = process * 280 - 140;
                rotateTransform.Angle = tAngle;
                da.To = tAngle;
            }
            rotateTransform.BeginAnimation(RotateTransform.AngleProperty, da);
        }
    }
}
